eth: implement EIP-7975 (eth/70 - partial block receipt lists)#33153
Conversation
|
|
||
| // RequestReceipts fetches a batch of transaction receipts from a remote node. | ||
| func (p *Peer) RequestReceipts(hashes []common.Hash, sink chan *Response) (*Request, error) { | ||
| func (p *Peer) RequestReceipts(hashes []common.Hash, gasUsed []uint64, sink chan *Response) (*Request, error) { |
There was a problem hiding this comment.
Please add a short comment that explains gasUsed in the function godoc comment.
| } | ||
|
|
||
| // Verify that the total number of transactions delivered is under the limit. | ||
| if uint64(previousTxs+lastReceipts.items.Len()) > gasUsed/21_000 { |
There was a problem hiding this comment.
EIP-2780 changes the intrinsic cost of transactions to 4500gas. To apply this, we have to find a way to relay the block timestamp of the block to which this receipt list is related. Then we can perform a fork parameter lookup to find the correct cost. It's annoying but we need this check.
| content, _, err := rlp.SplitList(it.Value()) | ||
| if err != nil { | ||
| return 0, fmt.Errorf("invalid receipt structure: %v", err) | ||
| } | ||
| rest := content | ||
| for range 3 { | ||
| _, _, rest, err = rlp.Split(rest) | ||
| if err != nil { | ||
| return 0, fmt.Errorf("invalid receipt structure: %v", err) | ||
| } | ||
| } | ||
| logsContent, _, err := rlp.SplitList(rest) | ||
| if err != nil { | ||
| return 0, fmt.Errorf("invalid receipt logs: %v", err) | ||
| } | ||
| log += uint64(len(logsContent)) |
There was a problem hiding this comment.
This code should live in a function in receipt.go. It is basically traversing the receipt object to find the logs data that should count towards the gas limit check.
| tresp = tracker.Response{ID: delivery.RequestId, MsgCode: ReceiptsMsg, Size: delivery.List.Len()} | ||
| if err = peer.tracker.Fulfil(tresp); err != nil { | ||
| t.Fatalf("tracker.Fulfil failed: %v", err) | ||
| } |
There was a problem hiding this comment.
I think invoking the tracker here does not have a purpose in the test. If you want to test the handler behavior as it is done by handler, you basically have to invoke the handler function directly.
There was a problem hiding this comment.
Since we reuse IDs the tracker would raise an ID collision error if a request with the same ID was not fulfilled.
However, I agree that the test itself is not well structured, and its is also strange to be in peer_test.go. Since wwe already have devp2p tests and TestGetBlockPartialReceipt, I think it is okay to remove these tests.
Convert the handler to the style used by the eth/69 handler, where the service* function returns a RawList.
merge error
Upstream v1.17.3 (PR ethereum#33153, commit 965bd6b, eth/70 partial receipt lists) made chain.go unconditionally load testdata/txinfo.json, which carries the LargeReceiptBlock hint used by ETH70 receipt tests. ETC's PoW chain doesn't expose ETH70 so LargeReceiptBlock has no meaningful value, but the file still has to exist for NewChain to succeed in the ethtest suite. Provide a stub with the field as null; the dependent test paths (suite.go LargeReceiptBlock checks) gracefully skip when the value is nil. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This is a draft PR to add support for EIP-7975.
Overall changes
lastBlockIncompletefield is true.RequestPartialReceipts).validateLastBlockReceipt.1f32d8959)